#region Copyright Vanderlande Industries B.V. 2011
//
// Copyright (c) 2011 Vanderlande Industries.
// All rights reserved.
//
// @file:     ControllerDateTime.cs
// @version:  %version: 3 %
// %date_created: woensdag 31 augustus 2011 9:35:28 %
//
// The copyright to the computer program(s) herein is the property of
// Vanderlande Industries. The program(s) may be used and/or copied
// only with the written permission of the owner or in accordance with
// the terms and conditions stipulated in the contract under which the
// program(s) have been supplied.
//
#endregion

﻿using System;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;

namespace VI.Fsc.OperatorGui.Models.Application
{
    public delegate void UpdateFscDateTimeEventHandler(DateTime newDate);

    /// <summary>
    /// Encapsulates a timer that requests the current time from server.
    /// This class is a singleton.
    /// </summary>
    public class CFscDateTime
    {
        private static CFscDateTime instance;
        private static object syncLock = new object();
        public event UpdateFscDateTimeEventHandler UpdateFscDateTimeEvent;

        // Thread used to update the controller time.
        private System.Threading.Timer updateServerDateTimer;

        /// <summary>
        /// Get the singleton instance.
        /// </summary>
        /// <returns>Reference to a single class.</returns>
        public static CFscDateTime Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncLock)
                    {
                        if (instance == null)
                        {
                            instance = new CFscDateTime();
                        }
                    }
                }

                return instance;
            }
        }

        private CFscDateTime()
        {
        }

        /// <summary>
        /// Starts/Stops requesting the date/time of the server.
        /// </summary>
        /// <param name="startRequesting">Flag indicating whether we want to start (true) or
        /// to stop (false) the request to the server.</param>
        public virtual void ToggleUpdateFscDateTime(bool startRequesting)
        {
            //Logger.Entering(MethodBase.GetCurrentMethod(), "startRequesting = " + startRequesting);

            if (startRequesting)
            {
                // Starts updating the controller date-time.
                updateServerDateTimer = new System.Threading.Timer(
                    new System.Threading.TimerCallback(UpdateFscDateTime),
                    null,
                    0/* start now */,
                    980 /* repeat it every 1 seconds */);
            }
            else
            {
                if (null != updateServerDateTimer)
                {
                    updateServerDateTimer.Dispose();
                    updateServerDateTimer = null;
                }
            }

            //Logger.Exiting(MethodBase.GetCurrentMethod());
        }

        /// <summary>
        /// Notifies about the new date/time of the server.
        /// </summary>
        /// <param name="info">This parameter is necessary because this method is called from a Thread.</param>
        public void UpdateFscDateTime(Object info)
        {
            //Logger.Entering(MethodBase.GetCurrentMethod(), "info = " + info);

            try
            {
                if (null != UpdateFscDateTimeEvent)
                {
                    UpdateFscDateTimeEvent(COPCServerConnectionService.Instance.GetServerDateTime());
                }
            }
            catch (ThreadAbortException e)
            {
                //Logger.Info(MethodBase.GetCurrentMethod(), "Trying to abort thread. " + e);
            }
            catch (Exception ex) // As in the RCF-Main program we exit if an exception arrives unhandled here.
            {
                //Logger.Fatal(MethodBase.GetCurrentMethod(), "Uncaught exception occurred.", ex);
                MessageBox.Show("Uncaught exception occurred: " + ex.Message + "\nSee log for details.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }

            //Logger.Exiting(MethodBase.GetCurrentMethod());
        }
    }
}
